/**
 * @file main.c
 * @author your name (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2023-08-22
 *
 * @copyright Copyright (c) 2023
 *
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <FreeRTOS.h>
#include <task.h>
#include "board.h"
#include "log.h"
#include "timers.h"
#include "lv_user_config.h"
#include "gui_guider.h"
#include "custom.h"
#include "events_init.h"
#include "lv_port_fs.h"
#include "wifi_event.h"
#include "homeAssistantMQTT.h"
#include "qyq_frame_modbus_master.h"

#define DBG_TAG "MAIN"

lv_ui guider_ui;
static homeAssisatnt_device_t ha_device;
TaskHandle_t modbus_tick_task_xhandle;
TaskHandle_t modbus_recv_task_xhandle;
static TimerHandle_t modbus_time;
volatile static qyq_frame_modbus_master_type_t qyq_frame_modbus_master;
volatile static qyq_frame_modbus_master_config_t qyq_frame_modbus_master_config;
struct bflb_device_s* uartx;
struct bflb_device_s* gpio;

uint8_t qyq_frame_modbus_master_writebuf[100];        // xmodem 写buf
uint32_t qyq_frame_modbus_master_writebuf_size = 100; // xmodem 写buf大小
uint8_t qyq_frame_modbus_master_readbuf[100];         // xmodem 读buf
uint32_t qyq_frame_modbus_master_readbuf_size = 100;  // xmodem 读buf大小

typedef struct
{
    uint32_t illu_value;    // 光照值    设备地址1
    uint16_t smoggy_status; //烟雾状态   设备地址2
    uint16_t pm1_0_value;   // 设备地址
    uint16_t pm2_5_value;
    uint16_t pm10_value;
    uint16_t temp_value;     //温度
    uint16_t humidity_value; //湿度
    uint16_t co2_value;      //CO2值
} disp_data_t;

disp_data_t disp_data;

uint8_t qyq_frame_modbus_master_config_write(uint8_t* buf, uint16_t length)
{
    uint16_t i = 0;
    bflb_gpio_set(gpio, GPIO_PIN_16);
    for (i = 0; i < length; i++) {
        bflb_uart_putchar(uartx, buf[i]);
    }
    vTaskDelay(pdMS_TO_TICKS(10));
    bflb_gpio_reset(gpio, GPIO_PIN_16);
    return 0;
}

void uart1_send(uint8_t* buf, uint16_t length)
{
    uint16_t i = 0;
    for (i = 0; i < length; i++) {
        bflb_uart_putchar(uartx, buf[i]);
    }
}

static void ha_event_cb(ha_event_t event, homeAssisatnt_device_t* ha_dev)
{
    switch (event)
    {
        case HA_EVENT_MQTT_CONNECED:
            LOG_I("<<<<<<<<<<  HA_EVENT_MQTT_CONNECED");
            static ha_sensor_entity_t sensor_co2 = {
                .name = "CO2",
                .unique_id = "co2_v1",
                .device_class = Class_carbon_dioxide,
                .unit_of_measurement = "ppm",
            };
            static ha_sensor_entity_t sensor_illum = {
                .name = "光照传感器",
                .unique_id = "illum",
                .device_class = Class_illuminance,
                .unit_of_measurement = "lx",
            };
            static ha_sensor_entity_t sensor_pm1 = {
                .name = "PM1",
                .unique_id = "pm_01",
                .device_class = Class_pm1,
                 .unit_of_measurement = "µg/m3",
            };
            static ha_sensor_entity_t sensor_pm10 = {
                .name = "PM10",
                .unique_id = "pm_10",
                .device_class = Class_pm10,
                .unit_of_measurement = "µg/m3",
            };
            static ha_sensor_entity_t sensor_pm25 = {
               .name = "PM2.5",
               .unique_id = "pm_25",
               .device_class = Class_pm25,
               .unit_of_measurement = "µg/m3",
            };
            static ha_Bsensor_entity_t binary_sensor = {
                .name = "烟雾传感器",
                .unique_id = "gas01",
                .device_class = Bclass_gas,
            };
            homeAssistant_device_add_entity(CONFIG_HA_ENTITY_SENSOR, &sensor_co2);
            homeAssistant_device_add_entity(CONFIG_HA_ENTITY_SENSOR, &sensor_illum);
            homeAssistant_device_add_entity(CONFIG_HA_ENTITY_SENSOR, &sensor_pm1);
            homeAssistant_device_add_entity(CONFIG_HA_ENTITY_SENSOR, &sensor_pm10);
            homeAssistant_device_add_entity(CONFIG_HA_ENTITY_SENSOR, &sensor_pm25);
            homeAssistant_device_add_entity(CONFIG_HA_ENTITY_BINARY_SENSOR, &binary_sensor);
            homeAssistant_device_send_status(HOMEASSISTANT_STATUS_ONLINE);
            homeAssistant_device_send_entity_state(CONFIG_HA_ENTITY_SENSOR, (ha_Bsensor_entity_t*)homeAssistant_fine_entity(CONFIG_HA_ENTITY_BINARY_SENSOR, "gas01"), 0);
            break;
        case HA_EVENT_MQTT_DISCONNECT:
            // LOG_I("<<<<<<<<<<  HA_EVENT_MQTT_DISCONNECT");
            // device_update_state(DEVICE_STATE_MQTT_DISCONNECT, false);
            break;
        case HA_EVENT_MQTT_COMMAND_LIGHT_SWITCH:

            break;
        case HA_EVENT_MQTT_COMMAND_LIGHT_RGB_UPDATE:


            break;
        default:
            break;
    }
}

void voice_task_process(void* msg);

void modbus_tick_task(void* msg)
{
    while (1) {
        qyq_frame_modbus_master.qyq_frame_modbus_master_tick(&qyq_frame_modbus_master);
        vTaskDelay(pdMS_TO_TICKS(1));
    }
}

void modbus_recv_task(void* msg)
{
    int ch;
    gpio = bflb_device_get_by_name("gpio");

    bflb_gpio_init(gpio, GPIO_PIN_16, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0);
    bflb_gpio_uart_init(gpio, GPIO_PIN_1, GPIO_UART_FUNC_UART1_TX);
    bflb_gpio_uart_init(gpio, GPIO_PIN_0, GPIO_UART_FUNC_UART1_RX);

    uartx = bflb_device_get_by_name("uart1");

    struct bflb_uart_config_s cfg;

    cfg.baudrate = 9600;
    cfg.data_bits = UART_DATA_BITS_8;
    cfg.stop_bits = UART_STOP_BITS_1;
    cfg.parity = UART_PARITY_NONE;
    cfg.flow_ctrl = 0;
    cfg.tx_fifo_threshold = 7;
    cfg.rx_fifo_threshold = 7;
    bflb_uart_init(uartx, &cfg);

    while (1) {
        ch = bflb_uart_getchar(uartx);
        if (ch != -1) {
            // printf("0x%02x ", ch);
            qyq_frame_modbus_master.qyq_frame_modbus_master_recv(&qyq_frame_modbus_master, ch);
        }
        vTaskDelay(pdMS_TO_TICKS(1));
    }
}


int main(void)
{
    board_init();
    if (0 != rfparam_init(0, NULL, 0)) {
        LOG_E("PHY RF init failed!\r\n");
        return 0;
    }
    staWiFiInit();
    uint8_t STA_MAC[6] = { 0 };
    // homeassistant_blufi_init(NULL)
    aiio_wifi_sta_mac_get(STA_MAC);
    ha_device.mqtt_info.mqtt_username = pvPortMalloc(128);
    memset(ha_device.mqtt_info.mqtt_username, 0, 128);
    sprintf(ha_device.mqtt_info.mqtt_username, "AiPi-UNO-ET485_sensor", STA_MAC[4], STA_MAC[5]);
    ha_device.name = ha_device.mqtt_info.mqtt_username;
    ha_device.mqtt_info.mqtt_keeplive = 60;
    ha_device.model = "AiPi-UNO-ET485";
    ha_device.mqtt_info.mqtt_clientID = ha_device.model;
    ha_device.hw_version = "Ai-M61-32S_V1.0";
    homeAssistant_device_init(&ha_device, ha_event_cb);

    lv_init();
    lv_port_disp_init();
    lv_port_indev_init();
    setup_ui(&guider_ui);

    xTaskCreate(lvgl_tick_task, (char*)"lvgl", 1024, NULL, 2, NULL);
    xTaskCreate(voice_task_process, (char*)"lvgl", 1024, NULL, 3, NULL);

    vTaskStartScheduler();
}

void voice_task_process(void* msg)
{
    int8_t ret = 0;
    uint8_t read_buf[10];
    uint32_t length;
    uint32_t value = 0;
    uint32_t send_value = 0;
    qyq_frame_modbus_master_config.qyq_frame_modbus_master_writebuf = qyq_frame_modbus_master_writebuf;
    qyq_frame_modbus_master_config.qyq_frame_modbus_master_readbuf = qyq_frame_modbus_master_readbuf;
    qyq_frame_modbus_master_config.qyq_frame_modbus_master_writebuf_size = qyq_frame_modbus_master_writebuf_size;
    qyq_frame_modbus_master_config.qyq_frame_modbus_master_readbuf_size = qyq_frame_modbus_master_readbuf_size;
    qyq_frame_modbus_master_config.qyq_frame_modbus_master_config_write = qyq_frame_modbus_master_config_write;

    if (qyq_frame_modbus_master_create(&qyq_frame_modbus_master, &qyq_frame_modbus_master_config) != 0) {
        printf("qyq_frame_modbus_master_create fail!\r\n");
    }
    xTaskCreate(modbus_tick_task, (char*)"modbus_tick_task", 1024, NULL, 26, &modbus_tick_task_xhandle);
    xTaskCreate(modbus_recv_task, (char*)"modbus_recv_task", 1024, NULL, 25, &modbus_recv_task_xhandle);

    disp_data.illu_value = 0;
    disp_data.smoggy_status = 0;
    disp_data.pm1_0_value = 0;
    disp_data.pm2_5_value = 0;
    disp_data.pm10_value = 0;
    disp_data.temp_value = 0;
    disp_data.humidity_value = 0;
    disp_data.co2_value = 0;

    while (1) {
        // 设备读取1

        ret = qyq_frame_modbus_master.qyq_frame_modbus_master_read_holding_registers(&qyq_frame_modbus_master, 0x01, 0x0002, 2, read_buf, &length);
        if (ret == 0) {
            value = 0;
            value = read_buf[0];
            value <<= 8;
            value |= read_buf[1];
            value <<= 8;
            value |= read_buf[2];
            value <<= 8;
            value |= read_buf[3];
            disp_data.illu_value = value / 1000;
            if (guider_ui.main_del)lv_label_set_text_fmt(guider_ui.main_label_lu_value, "%d", disp_data.illu_value);
            if (ha_device.mqtt_info.mqtt_connect_status)homeAssistant_device_send_entity_state(CONFIG_HA_ENTITY_SENSOR, (ha_sensor_entity_t*)homeAssistant_fine_entity(CONFIG_HA_ENTITY_SENSOR, "illum"), disp_data.illu_value);
        }
        // 设备读取2
        ret = qyq_frame_modbus_master.qyq_frame_modbus_master_read_holding_registers(&qyq_frame_modbus_master, 0x02, 0x0001, 1, read_buf, &length);
        if (ret == 0) {
            value = 0;
            value = read_buf[0];
            value <<= 8;
            value |= read_buf[1];
            disp_data.smoggy_status = value;
            if (ha_device.mqtt_info.mqtt_connect_status)homeAssistant_device_send_entity_state(CONFIG_HA_ENTITY_BINARY_SENSOR, (ha_Bsensor_entity_t*)homeAssistant_fine_entity(CONFIG_HA_ENTITY_BINARY_SENSOR, "gas01"), disp_data.smoggy_status);
        }
        // 设备读取3
        ret = qyq_frame_modbus_master.qyq_frame_modbus_master_read_holding_registers(&qyq_frame_modbus_master, 0x03, 0x0007, 3, read_buf, &length);
        printf("device addr:0x03 ret:%d length:%d\r\n", ret, length);
        if (ret == 0) {
            value = 0;
            value = read_buf[0];
            value <<= 8;
            value |= read_buf[1];
            disp_data.pm1_0_value = value;
            value = 0;
            value = read_buf[2];
            value <<= 8;
            value |= read_buf[3];
            disp_data.pm2_5_value = value;
            value = 0;
            value = read_buf[4];
            value <<= 8;
            value |= read_buf[5];
            disp_data.pm10_value = value;
            if (guider_ui.main_del) {
                lv_label_set_text_fmt(guider_ui.main_label_pm25_value, "%d", disp_data.pm2_5_value);
                lv_label_set_text_fmt(guider_ui.main_label_pm10_value, "%d", disp_data.pm10_value);
            }

            if (ha_device.mqtt_info.mqtt_connect_status) {
                homeAssistant_device_send_entity_state(CONFIG_HA_ENTITY_SENSOR, (ha_sensor_entity_t*)homeAssistant_fine_entity(CONFIG_HA_ENTITY_SENSOR, "pm_01"), disp_data.pm1_0_value);
                homeAssistant_device_send_entity_state(CONFIG_HA_ENTITY_SENSOR, (ha_sensor_entity_t*)homeAssistant_fine_entity(CONFIG_HA_ENTITY_SENSOR, "pm_10"), disp_data.pm10_value);
                homeAssistant_device_send_entity_state(CONFIG_HA_ENTITY_SENSOR, (ha_sensor_entity_t*)homeAssistant_fine_entity(CONFIG_HA_ENTITY_SENSOR, "pm_25"), disp_data.pm2_5_value);
            }
        }
        // 设备读取4
        ret = qyq_frame_modbus_master.qyq_frame_modbus_master_read_holding_registers(&qyq_frame_modbus_master, 0x04, 0x0002, 1, read_buf, &length);

        if (ret == 0) {
            value = 0;
            value = read_buf[0];
            value <<= 8;
            value |= read_buf[1];
            disp_data.co2_value = value;
            if (guider_ui.main_del)lv_label_set_text_fmt(guider_ui.main_label_2, "%d", disp_data.co2_value);
            if (ha_device.mqtt_info.mqtt_connect_status)homeAssistant_device_send_entity_state(CONFIG_HA_ENTITY_SENSOR, (ha_sensor_entity_t*)homeAssistant_fine_entity(CONFIG_HA_ENTITY_SENSOR, "co2_v1"), disp_data.co2_value);
        }

        LOG_I("illu=%d pm1=%d pm10=%d pm2.5=%d co2=%d file=%d", disp_data.illu_value, disp_data.pm1_0_value, disp_data.pm10_value, disp_data.pm2_5_value, disp_data.co2_value, disp_data.smoggy_status);
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}